package com.sdp.th.netty.channel;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.sdp.th.netty.utils.NettyUtils;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelId;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class ChannelManager {
	
	private ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	private final AttributeKey<ChannelSession> CHANNEL_SESSION = AttributeKey.newInstance("session");
	
	/**
	 * 设备通道MAP
	 */
	private final Map<String, Map<String, ChannelId>> channelIdMap;
	
	public ChannelManager() {
		channelIdMap = new ConcurrentHashMap<>();
	}

	/**
	 * 初始化通道，绑定通道关闭回调函数，给通道增加属性，绑定上设备编码和通道ID
	 * @param channel
	 * @return
	 */
	public boolean initChannel(Channel channel) {
		boolean added = channelGroup.add(channel);
		if(added) {
			ChannelSession session = new ChannelSession();
			session.setId(channel.id().toString());
			channel.attr(CHANNEL_SESSION).set(session);
			try {
				channel.closeFuture().addListener(remover);
			} catch (Exception e) {
				log.error("绑定通道关闭回调函数出现异常：{}",NettyUtils.stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
			}

		}
		
		return added;
	}
	
	/**
	 * 通道关闭的回调函数
	 */
	private ChannelFutureListener remover = new ChannelFutureListener() {
		@Override
		public void operationComplete(ChannelFuture future) throws Exception {
			ChannelSession session = future.channel().attr(CHANNEL_SESSION).get();
			if (session != null) {
				String deviceNo = session.getDeviceNo();
				if (!StringUtils.isEmpty(deviceNo)) {
					if (channelIdMap.containsKey(deviceNo)) {
						channelIdMap.get(deviceNo).remove(future.channel().id().toString());
					}
					
					//设备离线
//					ApplicationContextUtils.getBean(OfflineBusinessImpl.class).execute(deviceNo);

					
				}
				log.info("设备断开连接, 设备编号为：[{}]  客户端ip为：[{}], 通道ID: [{}]", StringUtils.isEmpty(deviceNo) ? "无" : deviceNo, future.channel().remoteAddress(), future.channel().id());

			}
		}
	};
	
	public boolean isChannelExist(ChannelId channelId) {
		return channelGroup.find(channelId) != null;
	}
	
	public boolean addMap(String deviceNo, Channel channel) {
		boolean added = false;
		Channel channelFind = channelGroup.find(channel.id());
		if (channelFind != null) {
			ChannelSession session = channel.attr(CHANNEL_SESSION).get();
			session.setDeviceNo(deviceNo);
			if (!channelIdMap.containsKey(deviceNo)) {
				channelIdMap.put(deviceNo, new ConcurrentHashMap<>());
			}
			channelIdMap.get(deviceNo).put(channel.id().toString(), channel.id());
		}
		return added;
	}
	
	
	public ChannelSession getSession(ChannelId channelId) {
    	if (channelId != null) {
    		Channel channel = channelGroup.find(channelId);
    		if (channel != null) {
    			return channel.attr(CHANNEL_SESSION).get();
			}
		}
        return null;
    }
}
